﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace IntelliTouchMix
{
    public partial class BlobController
    {
        TouchMouseEventArgs detectGesture(int i)
        {
            Point2f start = blobHistory[i][0].getPos();
            Point2f mid = blobHistory[i][lastFrameIndex[i] / 2].getPos();
            Point2f fin = blobHistory[i][lastFrameIndex[i]].getPos();
            Point2f vt = fin.sub(start);
            Point2f[] v = new Point2f[3];
            v[0] = mid.sub(start);
            v[1] = fin.sub(mid);
            v[2] = fin.sub(start);
            TouchMouseEventArgs e = null;
            // Check Movement
            if (v[0].dist2() + v[1].dist2() > 1.0f) // 15 25// Posible gesto
            { 
                Point2f v1 = mid.sub(start);
                Point2f v2 = fin.sub(mid);
                vt.normalize((float)Math.Sqrt((double)vt.dist2()));
                // Calculate Speed and set other global static variables
                TouchMouseEventArgs.setDistSpeedTimeVect(calcDistSpeedTimeVect(i));
                Blobs avgBlob = averageBlobFromFrames(i);
               
                /*   else if (detectCircle(i))
                   {
                       MessageBox.Show("Exito Circlulo");
                       // else
                       //       MessageBox.Show("Failed No circulo");

                       return;
                   }*/
                //detectFingerDown(i);
                e = detectL(i);
                if (e != null)
                {
                    // Call the handler
                    if (GestureHandler != null)
                    {
                        // MessageBox.Show("Hola");
                        GestureHandler(this, e);
                    }
                    if (blobGestureHandler[i] != null)
                    {
                        blobGestureHandler[i](this, e);
                    }
                    freeFrame(i);
                    return e;
                } 
                e = detectHerradura(i);
                if (e != null)
                {
                    // Call the handler
                    /*if (GestureHandler != null)
                    {
                        // MessageBox.Show("Hola");
                        GestureHandler(this, e);
                    }
                    if (blobGestureHandler[i] != null)
                    {
                        blobGestureHandler[i](this, e);
                    }*/
                    freeFrame(i);
                    return e;
                }

                if (vt.y > hLimit)
                {
                    // if (detectFingerDown(i)) { }
                    if (avgBlob.getNPixels() > thumpLimit)
                    {
                        e = TouchMouseEventArgs.Finger(DirectionType.DOWN, FingerType.BIG_FINGER);
                        if(blobEventType[i]==EventType.ONE_SHOT)
                            blobGestureHandler[i] = (Gesture)BigFingerDownHandler;
                        else if(blobEventType[i]==EventType.REAL_TIME)
                            blobGestureHandler[i] = (Gesture)BigFingerDownRealTimeHandler;

                        // MessageBox.Show("Change to the previous  three fingers effect " + vt);
                    }
                    else
                    {
                        // posible one blob doing this...
                        switch (findVerticalFingers())
                        {
                            case 1:
                                e = TouchMouseEventArgs.Finger(DirectionType.DOWN, FingerType.ONE_FINGER);
                                if (blobEventType[i] == EventType.ONE_SHOT)
                                    blobGestureHandler[i] = (Gesture)OneFingerDownHandler;
                                else if (blobEventType[i] == EventType.REAL_TIME)
                                    blobGestureHandler[i] = (Gesture)OneFingerDownRealTimeHandler;
                                    //MessageBox.Show("Volumen Down");
                                break;
                            case 2:
                                e = TouchMouseEventArgs.Finger(DirectionType.DOWN, FingerType.TWO_FINGERS);
                                if (blobEventType[i] == EventType.ONE_SHOT)
                                    blobGestureHandler[i] = (Gesture)TwoFingersDownHandler;
                                else if (blobEventType[i] == EventType.REAL_TIME)
                                    blobGestureHandler[i] = (Gesture)TwoFingersDownRealTimeHandler;
                                    //MessageBox.Show("Two Fingers");
                                    break;
                            case 3:
                                e = TouchMouseEventArgs.Finger(DirectionType.DOWN, FingerType.THREE_FINGERS);
                                if (blobEventType[i] == EventType.ONE_SHOT)
                                    blobGestureHandler[i] = (Gesture)ThreeFingersDownHandler;
                                else if (blobEventType[i] == EventType.REAL_TIME)
                                    blobGestureHandler[i] = (Gesture)ThreeFingersDownRealTimeHandler;
                                        //MessageBox.Show("Three Fingers");
                                break;
                        }
                    }
                }
                else if (vt.y < -hLimit)
                {
                    if (avgBlob.getNPixels() > thumpLimit)
                    {
                        e = TouchMouseEventArgs.Finger(DirectionType.UP, FingerType.BIG_FINGER);
                        if (blobEventType[i] == EventType.ONE_SHOT)
                                    blobGestureHandler[i] = (Gesture)BigFingerUpHandler;
                        else if (blobEventType[i] == EventType.REAL_TIME)
                                    blobGestureHandler[i] = (Gesture)BigFingerUpRealTimeHandler;
                        //MessageBox.Show("Change to the next  three fingers effect");
                    }
                    else
                    {
                        // posible one blob doing this...
                        switch (findVerticalFingers())
                        {
                            case 1:
                                e = TouchMouseEventArgs.Finger(DirectionType.UP, FingerType.ONE_FINGER);
                                if (blobEventType[i] == EventType.ONE_SHOT)
                                    blobGestureHandler[i] = (Gesture)OneFingerUpHandler;
                                else if (blobEventType[i] == EventType.REAL_TIME)
                                    blobGestureHandler[i] = (Gesture)OneFingerUpRealTimeHandler;
                                //MessageBox.Show("Volumen Up");
                                break;
                            case 2:
                                e = TouchMouseEventArgs.Finger(DirectionType.UP, FingerType.TWO_FINGERS);
                                if (blobEventType[i] == EventType.ONE_SHOT)
                                    blobGestureHandler[i] = (Gesture)TwoFingersUpHandler;
                                else if (blobEventType[i] == EventType.REAL_TIME)
                                    blobGestureHandler[i] = (Gesture)TwoFingersUpRealTimeHandler;
                                //MessageBox.Show("Two Fingers");
                                break;
                            case 3:
                                e = TouchMouseEventArgs.Finger(DirectionType.UP, FingerType.THREE_FINGERS);
                                if (blobEventType[i] == EventType.ONE_SHOT)
                                    blobGestureHandler[i] = (Gesture)ThreeFingersUpHandler;
                                else if (blobEventType[i] == EventType.REAL_TIME)
                                    blobGestureHandler[i] = (Gesture)ThreeFingersUpRealTimeHandler;
                                //MessageBox.Show("Three Fingers");
                                break;
                        }


                    }
                }
                else if (vt.x > hLimit)
                {
                    if (avgBlob.getNPixels() > thumpLimit)
                    {
                        e = TouchMouseEventArgs.Finger(DirectionType.RIGHT, FingerType.BIG_FINGER);
                        if (blobEventType[i] == EventType.ONE_SHOT)
                                    blobGestureHandler[i] = (Gesture)BigFingerRightHandler;
                        else if (blobEventType[i] == EventType.REAL_TIME)
                                    blobGestureHandler[i] = (Gesture)BigFingerRightRealTimeHandler;
                        //MessageBox.Show("Change to the Next sample" + vt);
                    }
                    else
                    {

                        ////////////
                        // posible one blob doing this...
                        switch (findHorizontalFingers())
                        {
                            case 1:
                                e = TouchMouseEventArgs.Finger(DirectionType.RIGHT, FingerType.ONE_FINGER);
                                if (blobEventType[i] == EventType.ONE_SHOT)
                                    blobGestureHandler[i] = (Gesture)OneFingerRightHandler;
                                else if (blobEventType[i] == EventType.REAL_TIME)
                                    blobGestureHandler[i] = (Gesture)OneFingerRightRealTimeHandler;
                                //MessageBox.Show("Volumen Down");
                                break;
                            case 2:
                                e = TouchMouseEventArgs.Finger(DirectionType.RIGHT, FingerType.TWO_FINGERS);
                                if (blobEventType[i] == EventType.ONE_SHOT)
                                    blobGestureHandler[i] = (Gesture)TwoFingersRightHandler;
                                else if (blobEventType[i] == EventType.REAL_TIME)
                                    blobGestureHandler[i] = (Gesture)TwoFingersRightRealTimeHandler;
                                //MessageBox.Show("Two Fingers");
                                break;
                            case 3:
                                e = TouchMouseEventArgs.Finger(DirectionType.RIGHT, FingerType.THREE_FINGERS);
                                if (blobEventType[i] == EventType.ONE_SHOT)
                                    blobGestureHandler[i] = (Gesture)ThreeFingersRightHandler;
                                else if (blobEventType[i] == EventType.REAL_TIME)
                                    blobGestureHandler[i] = (Gesture)ThreeFingersRightRealTimeHandler;
                                //MessageBox.Show("Three Fingers");
                                break;
                        }
                    }
                }
                else if (vt.x < -0.83f && avgBlob.getNPixels() > thumpLimit)//-hLimit)
                {
                    e = TouchMouseEventArgs.Finger(DirectionType.LEFT, FingerType.BIG_FINGER);
                    if (blobEventType[i] == EventType.ONE_SHOT)
                                    blobGestureHandler[i] = (Gesture)BigFingerLeftHandler;
                        else if(blobEventType[i]==EventType.REAL_TIME)
                                    blobGestureHandler[i] = (Gesture)BigFingerLeftRealTimeHandler;
                    //MessageBox.Show("Change to the previous sample"+vt);
                }
                else if (vt.x < -hLimit)
                {
                    ///////////
                    ////////////
                    // posible one blob doing this...
                    switch (findHorizontalFingers())
                    {
                        case 1:
                            e = TouchMouseEventArgs.Finger(DirectionType.LEFT, FingerType.ONE_FINGER);
                            if (blobEventType[i] == EventType.ONE_SHOT)
                                blobGestureHandler[i] = (Gesture)OneFingerLeftHandler;
                            else if (blobEventType[i] == EventType.REAL_TIME)
                                blobGestureHandler[i] = (Gesture)OneFingerLeftRealTimeHandler;
                            break;
                        case 2:
                            e = TouchMouseEventArgs.Finger(DirectionType.LEFT, FingerType.TWO_FINGERS);
                            if (blobEventType[i] == EventType.ONE_SHOT)
                                blobGestureHandler[i] = (Gesture)TwoFingersLeftHandler;
                            else if (blobEventType[i] == EventType.REAL_TIME)
                                blobGestureHandler[i] = (Gesture)TwoFingersLeftRealTimeHandler;
                            break;
                        case 3:
                            e = TouchMouseEventArgs.Finger(DirectionType.LEFT, FingerType.THREE_FINGERS);
                            if (blobEventType[i] == EventType.ONE_SHOT)
                                blobGestureHandler[i] = (Gesture)ThreeFingersLeftHandler;
                            else if (blobEventType[i] == EventType.REAL_TIME)
                                blobGestureHandler[i] = (Gesture)ThreeFingersLeftRealTimeHandler;
                            break;
                    }
                }
                else if (vt.x > vLimit && vt.y < -vLimit)
                {
                    if (avgBlob.getNPixels() > thumpLimit)
                    {
                        e = TouchMouseEventArgs.Finger(DirectionType.UP_RIGHT, FingerType.BIG_FINGER);
                        if (blobEventType[i] == EventType.ONE_SHOT)
                                    blobGestureHandler[i] = (Gesture)BigVerticalUpRightHandler;
                        else if (blobEventType[i] == EventType.REAL_TIME)
                                    blobGestureHandler[i] = (Gesture)BigVerticalUpRightRealTimeHandler;
                        //MessageBox.Show("Thum Fadeout the first Song and Fading the second song. " + vt);
                    }
                    else
                    {
                        e = TouchMouseEventArgs.Finger(DirectionType.UP_RIGHT, FingerType.ONE_FINGER);
                        if (blobEventType[i] == EventType.ONE_SHOT)
                                    blobGestureHandler[i] = (Gesture)VerticalUpRightHandler;
                        else if (blobEventType[i] == EventType.REAL_TIME)
                                    blobGestureHandler[i] = (Gesture)VerticalUpRightRealTimeHandler;
                        //MessageBox.Show("Fadeout the first Song and Fading the second song. " + vt);
                    }

                }
                else if (vt.x < -vLimit && vt.y < -vLimit)
                {
                    if (avgBlob.getNPixels() > thumpLimit)
                    {
                        e = TouchMouseEventArgs.Finger(DirectionType.UP_LEFT, FingerType.BIG_FINGER);
                        if (blobEventType[i] == EventType.ONE_SHOT)
                                    blobGestureHandler[i] = (Gesture)BigVerticalUpLeftHandler;
                        else if (blobEventType[i] == EventType.REAL_TIME)
                                    blobGestureHandler[i] = (Gesture)BigVerticalUpLeftRealTimeHandler;
                        // MessageBox.Show("thump Select the previous song…. " + vt);
                    }
                    else
                    {
                        e = TouchMouseEventArgs.Finger(DirectionType.UP, FingerType.ONE_FINGER);
                        if (blobEventType[i] == EventType.ONE_SHOT)
                                    blobGestureHandler[i] = (Gesture)VerticalUpLeftHandler;
                        else if (blobEventType[i] == EventType.REAL_TIME)
                                    blobGestureHandler[i] = (Gesture)VerticalUpLeftRealTimeHandler;
                        // MessageBox.Show("Select the previous song…." + vt);
                    }

                }
                else if (vt.x > vLimit && vt.y > vLimit)
                {
                    if (avgBlob.getNPixels() > thumpLimit)
                    {
                        e = TouchMouseEventArgs.Finger(DirectionType.DOWN_RIGHT, FingerType.BIG_FINGER);
                        if (blobEventType[i] == EventType.ONE_SHOT)
                                    blobGestureHandler[i] = (Gesture)BigVerticalDownRightHandler;
                        else if (blobEventType[i] == EventType.REAL_TIME)
                                    blobGestureHandler[i] = (Gesture)BigVerticalDownRightRealTimeHandler;
                        // MessageBox.Show("THum Select the next song " + vt);
                    }
                    else
                    {
                        e = TouchMouseEventArgs.Finger(DirectionType.DOWN_RIGHT, FingerType.ONE_FINGER);
                        if (blobEventType[i] == EventType.ONE_SHOT)
                                    blobGestureHandler[i] = (Gesture)VerticalDownRightHandler;
                        else if(blobEventType[i]==EventType.REAL_TIME)
                                    blobGestureHandler[i] = (Gesture)VerticalDownRightRealTimeHandler;
                        // MessageBox.Show("Select the next song" + vt);
                    }
                }
                else if (vt.x < -vLimit && vt.y > vLimit)
                {
                    if (avgBlob.getNPixels() > thumpLimit)
                    {
                        e = TouchMouseEventArgs.Finger(DirectionType.DOWN_LEFT, FingerType.BIG_FINGER);
                        if (blobEventType[i] == EventType.ONE_SHOT)
                                    blobGestureHandler[i] = (Gesture)BigVerticalDownLeftHandler;
                        else if(blobEventType[i]==EventType.REAL_TIME)
                                    blobGestureHandler[i] = (Gesture)BigVerticalDownLeftRealTimeHandler;
                        // MessageBox.Show("Thumps Play sample" + vt);
                    }
                    else
                    {
                        e = TouchMouseEventArgs.Finger(DirectionType.DOWN_LEFT, FingerType.ONE_FINGER);
                        if (blobEventType[i] == EventType.ONE_SHOT)
                                    blobGestureHandler[i] = (Gesture)VerticalDownLeftHandler;
                        else if(blobEventType[i]==EventType.REAL_TIME)
                                    blobGestureHandler[i] = (Gesture)VerticalDownLeftRealTimeHandler;
                        // MessageBox.Show("Play sample" + vt);
                    }
                }
                /*  if (avgBlob.getNPixels() > thumpLimit) // 9
                      MessageBox.Show("thump " + avgBlob.getNPixels() + " V2 " + vin.dist2().ToString());
                  else
                      MessageBox.Show("Finger " + avgBlob.getNPixels() + " V2 " + vin.dist2().ToString());
                  */
                if (e != null)
                {
                    // Call the handler
                    if (GestureHandler != null)
                    {
                        // MessageBox.Show("Hola");
                        GestureHandler(this, e);
                    }
                    if (blobGestureHandler[i] != null)
                    {
                        blobGestureHandler[i](this, e);
                    }
                }
            }
            else if (v[0].dist2() + v[1].dist2() > 0.0f)
            {
                // detectFingerDown(i);
                // detecta el material
                e = new TouchMouseEventArgs();
                int maxPixel = averageBlobFromFrames(i).getMaxPixel();
                if (maxPixel > 140)
                {
                    e.materialType = MaterialType.SKIN;
                    blobGestureHandler[i] = MaterialSkinHandler;
                }
                else if (maxPixel > 90){
                    e.materialType = MaterialType.HAIR;
                    blobGestureHandler[i] = MaterialHairHandler;
                }
                else if (maxPixel > 40){
                    e.materialType = MaterialType.PAPER;
                    blobGestureHandler[i] = MaterialPaperHandler;
                }
                else {
                    blobGestureHandler[i] = MaterialClothesHandler;
                    e.materialType = MaterialType.CLOTHES;
                }
                    // cloth
                if (e != null)
                {

                    // Call the handler
                    if (MaterialHandler != null)
                    {
                        // MessageBox.Show("Hola");
                        MaterialHandler(this, e);
                    }
                    if (blobGestureHandler[i] != null)
                    {
                        blobGestureHandler[i](this, e);
                    }
                }
              //  MessageBox.Show("prom " + averageBlobFromFrames(i).ToString());
            }
            // detected
            freeFrame(i);
            return e;
            // Compare with the gestures

            // MessageBox.Show("inicio " + blobHistory[i][0] + "Medio " + blobHistory[i][lastFrameIndex[i]/2] + " Termino " + blobHistory[i][lastFrameIndex[i]]);

        }
        ///***
        /***
         * Return the number of fingers going down
         */ 
        int findVerticalFingers()
        {
            int num = 0;
            for (int i = 0; i < this.maxBlobs; ++i)
            {
                if (lastFrameIndex[i] > 2)
                {
                    Point2f start = blobHistory[i][0].getPos();
                    Point2f fin = blobHistory[i][lastFrameIndex[i]].getPos();
                    Point2f vt = fin.sub(start);
                    // Check Movement
                    if (vt.dist2() > 5.0f) // 15
                    {
                        // num++;
                        //    freeFrame(i);

                        if (vt.y > hLimit)
                        {
                            // Delete blob current frame 
                            freeFrame(i);
                            num++;
                        }
                        else if (vt.y < -hLimit)
                        {
                            num++; //--
                            // Delete blob current frame
                            freeFrame(i);
                        }

                    }
                }
            }
            return num;
        }
        int findHorizontalFingers()
        {
            int num = 0;
            for (int i = 0; i < this.maxBlobs; ++i)
            {
                if (lastFrameIndex[i] > 2)
                {
                    Point2f start = blobHistory[i][0].getPos();
                    Point2f fin = blobHistory[i][lastFrameIndex[i]].getPos();
                    Point2f vt = fin.sub(start);
                    // Check Movement
                    if (vt.dist2() > 5.0f) // 15
                    {
                        // num++;
                        //    freeFrame(i);

                        if (vt.x > hLimit)
                        {
                            // Delete blob current frame 
                            freeFrame(i);
                            num++;
                        }
                        else if (vt.x < -hLimit)
                        {
                            num++; //--
                            // Delete blob current frame
                            freeFrame(i);
                        }

                    }
                }
            }
            return num;
        }
        /** **/
        public event Gesture GestureHandler;
        public event Gesture OneFingerUpHandler;
        public event Gesture OneFingerDownHandler;
        public event Gesture OneFingerLeftHandler;
        public event Gesture OneFingerRightHandler;
        public event Gesture OneFingerUpRealTimeHandler;
        public event Gesture OneFingerDownRealTimeHandler;
        public event Gesture OneFingerLeftRealTimeHandler;
        public event Gesture OneFingerRightRealTimeHandler;
        public event Gesture BigFingerUpHandler;
        public event Gesture BigFingerDownHandler;
        public event Gesture BigFingerLeftHandler;
        public event Gesture BigFingerRightHandler;
        public event Gesture BigFingerUpRealTimeHandler;
        public event Gesture BigFingerDownRealTimeHandler;
        public event Gesture BigFingerLeftRealTimeHandler;
        public event Gesture BigFingerRightRealTimeHandler;
        public event Gesture TwoFingersUpHandler;
        public event Gesture TwoFingersDownHandler;
        public event Gesture TwoFingersUpRealTimeHandler;
        public event Gesture TwoFingersDownRealTimeHandler;
        public event Gesture ThreeFingersUpHandler;
        public event Gesture ThreeFingersDownHandler;
        public event Gesture ThreeFingersUpRealTimeHandler;
        public event Gesture ThreeFingersDownRealTimeHandler;


        public event Gesture TwoFingersLeftHandler;
        public event Gesture TwoFingersRightHandler;
        public event Gesture TwoFingersLeftRealTimeHandler;
        public event Gesture TwoFingersRightRealTimeHandler;
        public event Gesture ThreeFingersLeftHandler;
        public event Gesture ThreeFingersRightHandler;
        public event Gesture ThreeFingersLeftRealTimeHandler;
        public event Gesture ThreeFingersRightRealTimeHandler;

        public event Gesture VerticalUpLeftHandler;
        public event Gesture VerticalUpRightHandler;
        public event Gesture VerticalDownLeftHandler;
        public event Gesture VerticalDownRightHandler;
        public event Gesture BigVerticalUpLeftHandler;
        public event Gesture BigVerticalUpRightHandler;
        public event Gesture BigVerticalDownLeftHandler;
        public event Gesture BigVerticalDownRightHandler;

        public event Gesture VerticalUpLeftRealTimeHandler;
        public event Gesture VerticalUpRightRealTimeHandler;
        public event Gesture VerticalDownLeftRealTimeHandler;
        public event Gesture VerticalDownRightRealTimeHandler;
        public event Gesture BigVerticalUpLeftRealTimeHandler;
        public event Gesture BigVerticalUpRightRealTimeHandler;
        public event Gesture BigVerticalDownLeftRealTimeHandler;
        public event Gesture BigVerticalDownRightRealTimeHandler;

        public event Gesture UPositiveHandler;
        public event Gesture UNegativeHandler;
        public event Gesture UInvertedPositiveHandler;
        public event Gesture UInvertedNegativeHandler;
        public event Gesture CPositiveHandler;
        public event Gesture CNegativeHandler;
        public event Gesture CInvertedPositiveHandler;
        public event Gesture CInvertedNegativeHandler;
        public event Gesture CirclePositiveHandler;
        public event Gesture CircleNegativeHandler;
        public event Gesture CirclePositiveRealTimeHandler;
        public event Gesture CircleNegativeRealTimeHandler;
        public event Gesture MaterialCoverHandler;
        public event Gesture FingerUpHandler;
        public event Gesture FingerDownHandler;
        public event Gesture MaterialHandler;
        public event Gesture MaterialPaperHandler;
        public event Gesture MaterialClothesHandler;
        public event Gesture MaterialHairHandler;
        public event Gesture MaterialSkinHandler;

        public event Gesture LLeftDown;
        public event Gesture LDownRight;
        public event Gesture LRightUp;
        public event Gesture LUpLeft;

        public event Gesture LDownLeft;
        public event Gesture LRightDown;
        public event Gesture LUpRight;
        public event Gesture LLeftUp;
    }
}
